#ifndef GPU_LINE_DART_H
#define GPU_LINE_DART_H

#include <cuda.h>
#include <curand_kernel.h>
#include "vectorGpu.h"
#include "gpuDart.h"

class GPULineDart : public GPUDart
{
public:
	GPULineDart();
	virtual ~GPULineDart();

	virtual bool init(unsigned int m, DATA_TYPE radius, unsigned int d);
	virtual void setupDarts();
	virtual void updateIntervals();
	virtual void updateIntervals2();
	virtual void pickPoint();
	virtual void addSamples();
	virtual void downloadSamples();
	virtual unsigned int getNumGeneratedSamples();

protected:
	unsigned int* d_numSamples;
	unsigned int* d_failureCount;
};

namespace GPULineDartCuda
{
	__global__ void initRandomStates(curandState* randStates);
	__global__ void setupGPUDarts(curandState* randStates, GPUDart::GPUInterval* intervals, GPUDart::GPUMDVector refPoints);
	__global__ void updateIntervalsKernel(GPUDart::GPUMDVector samples, GPUDart::GPUInterval* intervals,
		unsigned int *pNumSamples, GPUDart::GPUMDVector refPoints);
	__global__ void updateIntervals2Kernel(GPUDart::GPUMDVector samples, GPUDart::GPUInterval* intervals,
		unsigned int *pNumSamples, GPUDart::GPUMDVector refPoints);
	__global__ void pickPointKernel(curandState* randStates, GPUDart::GPUInterval* intervals, GPUDart::GPUMDVector refPoints);
	__global__ void addSamplesKernel(GPUDart::GPUMDVector samples,
		unsigned int *pNumSamples, unsigned int* pFailureCount, GPUDart::GPUMDVector refPoints);
};

#endif